#include "Game.h"
#include "../GameplayStates/IntroState.h"
#include "../GameplayStates/MainMenuState.h"
#include "../GameplayStates/GameplayState.h"

CGame::~CGame(void)
{

}

CGame* CGame::GetInstance( void )
{
	static CGame s_Instance;
	return &s_Instance;
}

CGame::CGame( void )
{	
	m_nWidth = 1;
	m_nHeight = 1;
	m_bIsWindowed = true;
	m_dwCurrTime = 0;
	m_pCurrState = nullptr;
}

void CGame::Initialize( HWND hWnd, HINSTANCE hInstance,
						int nScreenWidth, int nScreenHeight,
						bool bIsWindowed )
{
	m_nWidth = nScreenWidth;
	m_nHeight = nScreenHeight;
	m_bIsWindowed = bIsWindowed;


	m_pD3D = CSGD_Direct3D::GetInstance();
	m_pTM  = CSGD_TextureManager::GetInstance();
	m_pDI  = CSGD_DirectInput::GetInstance();
	m_pXA  = CSGD_XAudio2::GetInstance();

	
	m_pD3D->InitDirect3D( hWnd, m_nWidth, m_nHeight, m_bIsWindowed, false );
	m_pTM->InitTextureManager( m_pD3D->GetDirect3DDevice(), m_pD3D->GetSprite() );
	m_pDI->InitDirectInput( hWnd, hInstance, DI_KEYBOARD | DI_MOUSE );
	m_pXA->InitXAudio2();

	

	m_dwCurrTime = GetTickCount();

	//AddState(CGameplayState::GetInstance());
	AddState(CIntroState::GetInstance());

	//RemoveState();
}

bool CGame::Main( void )
{
	// Call the private helper functions
	if( Input() == false )
		return false;

	Update();
	Render();
	return true;
}

void CGame::Shutdown( void )
{
	//AddState( nullptr );
	//RemoveState();
	//RemoveState();
	if(this->m_pD3D)
	{
		m_pD3D->ShutdownDirect3D();
		m_pD3D = nullptr;
	}
	if(this->m_pDI)
	{
		m_pDI->ShutdownDirectInput();
		m_pDI = nullptr;
	}
	if(this->m_pTM)
	{
		m_pTM->ShutdownTextureManager();
		m_pTM = nullptr;
	}
	if(this->m_pXA)
	{
		m_pXA->ShutdownXAudio2();
		m_pXA = nullptr;
	}
}

bool CGame::Input(void)
{
	m_pDI->ReadDevices();
	GameIter iter;
	iter = m_lGames.end();
	iter--;
	return(*iter)->Input();
	return true;
}

void CGame::Update( void )
{
//	m_pXA->Update();

	DWORD dwNow = GetTickCount();

	float fElapsedSeconds = float(dwNow - m_dwCurrTime) / 1000.0f;

	m_dwCurrTime = dwNow;

	if( fElapsedSeconds > 0.125f )
		fElapsedSeconds = 0.125f;

	GameIter iter;
	iter = m_lGames.end();	//NEED THIS!! BELOW

	//while(iter != m_lGames.end())
	//{
	//	(*iter)->Update(fElapsedSeconds);
	//	iter++;
	//}

	iter--;
	if (CGameplayState::GetInstance()->GetPaused() == false)
	(*iter)->Update(fElapsedSeconds);
}

void CGame::Render( void )
{
	m_pD3D->Clear( 0,0,0 );

	m_pD3D->DeviceBegin();
	m_pD3D->SpriteBegin();

	//m_pD3D->DrawText( _T("Hello World!"), 0, 0, 255, 255, 255 );

//	m_pCurrState->Render();
	GameIter iter;
	iter = m_lGames.begin();
	while(iter != m_lGames.end())
	{
		(*iter)->Render();
		iter++;
	}
	m_pD3D->SpriteEnd();
	m_pD3D->DeviceEnd();
	m_pD3D->Present();
}

void CGame::AddState( IGameState* pNextState )
{
	/*if(m_pCurrState != nullptr)
	{
		m_lGames.push_back(m_pCurrState);
	}
	m_pCurrState = pNextState;*/
	if(pNextState != nullptr)
	{
		m_pCurrState = pNextState;
		m_lGames.push_back(m_pCurrState);
	}

	if(m_pCurrState != nullptr)
		m_pCurrState->Enter();
}

void CGame::RemoveState(IGameState* pStateToBeRemoved)
{
	if(m_lGames.size() > 0)
	{
		GameIter theit = m_lGames.begin();
		while(*theit != pStateToBeRemoved)
		theit++;
		m_pCurrState = *theit;
		m_pCurrState->Exit();
		theit = m_lGames.erase(theit);
	}
}

//void CGame::ChangeState( IGameState* pNextState )
//{
//// Clean up the existing state (if any)
//	if( m_pCurrState != nullptr )
//		m_pCurrState->Exit();
//
//// Store the new state
//	m_pCurrState = pNextState;
//
//// Setup the new state (if any)
//	if( m_pCurrState != nullptr )
//		m_pCurrState->Enter();
//}